import SEED from './seed'
import sodium from 'sodium-native'
import crypto from 'crypto'

{crypto_scalarmult, crypto_sign_ed25519_pk_to_curve25519, crypto_sign_verify_detached, crypto_sign_BYTES, crypto_sign_detached, sodium_malloc} = sodium

# 因为从私钥计算公钥比较昂贵，而签名又需要公钥，ed25519私钥所以包含了私钥和公钥

ed25519_x25519_pk_sk = (seed)=>
  pk = Buffer.allocUnsafe(sodium.crypto_sign_PUBLICKEYBYTES)
  sk = Buffer.allocUnsafe(sodium.crypto_sign_SECRETKEYBYTES)
  sodium.crypto_sign_seed_keypair(pk,sk,seed)

  xpk = Buffer.allocUnsafe sodium.crypto_box_PUBLICKEYBYTES
  xsk = Buffer.allocUnsafe sodium.crypto_box_SECRETKEYBYTES
  crypto_sign_ed25519_pk_to_curve25519 xpk, pk
  sodium.crypto_sign_ed25519_sk_to_curve25519 xsk, sk
  return [pk, sk, xpk, xsk]

[EPK,ESK,XPK,XSK] = ed25519_x25519_pk_sk SEED

export ESK = ESK
export EPK = EPK
export XPK = XPK
export XSK = XSK


export ed25519Sign = (msg)=>
  sign = Buffer.allocUnsafe crypto_sign_BYTES
  crypto_sign_detached sign, msg, ESK
  return sign

# sign, msg, EPK
export ed25519Verify = crypto_sign_verify_detached

export epk2xpk = (epk)=>
  xpk = Buffer.allocUnsafe 32
  crypto_sign_ed25519_pk_to_curve25519 xpk, epk
  xpk

export xpkSecret = (xpk)=>
  secret = Buffer.allocUnsafe 32
  crypto_scalarmult(secret, XSK, xpk)
  secret

# do =>
#   seed2 = crypto.randomBytes(32)
#   [pk2, sk2, xpk2, xsk2] = ed25519_x25519_pk_sk seed2
#
#   k1 = Buffer.allocUnsafe(32)
#   crypto_scalarmult(k1, xsk2, XPK)
#   console.log k1
#
#   console.log epkSecret(pk2)


  # msg = Buffer.from "x1test","utf8"
  # console.log sign.length, sign
  #
  # console.log crypto_sign_verify_detached(sign, msg, EPK)

# export XSK = new X25519SecretKey(SEED)
# export XPK = undefined
# export ESK = undefined
# export EPK = undefined
#
# export init = =>
#   sodium = await SodiumPlus.auto()
#   backend = sodium.backend
#   XPK = await sodium.crypto_box_publickey_from_secretkey(XSK)
#   pk = XPK.getBuffer()
#   ESK = new Ed25519SecretKey(Buffer.concat [SEED, pk])
#   console.log sodium.backend.crypto_sign_ed25519_sk_to_pk
#   EPK = new Ed25519PublicKey(pk)
#
#   # pair = await sodium.crypto_sign_keypair()
#   # pk = await sodium.crypto_sign_publickey(pair)
#   # console.log pk.getBuffer()
#   # sk = await sodium.crypto_sign_secretkey(pair)
#   # console.log sk.getBuffer()[32..]

# do =>
  # await init()
  # console.log XPK
  # backend = sodium.backend
  #
  # sign = await backend.crypto_sign_detached(msg, ESK)
  # console.log sign
  # console.log await sodium.crypto_sign_verify_detached(msg, EPK, sign)

  # console.log "sk"
  # console.log SEED
  # console.log sk.getBuffer()
  #
  # console.log "pk"
  # console.log pk.getBuffer()
  #
  # rsk = new X25519SecretKey(crypto.randomBytes(32))
  # rpk = await sodium.crypto_box_publickey_from_secretkey(rsk)
  #
  # nonce = crypto.randomBytes(24)
  # txt = crypto.randomBytes(1024)
  # console.log txt
  #
  # n = 0
  # begin = new Date() - 0
  # while ++n<10000
  #   ciphertext = await backend.crypto_box(txt, nonce, sk, rpk)
  # end = new Date() - begin
  # console.log "cost", end/1000
  # console.log ciphertext.length
  #
  # decrypted = await backend.crypto_box_open(ciphertext, nonce, rsk, pk)
  # console.log decrypted
  #
